package com.gitee.qdbp.general.common.biz.settings.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.jdbc.ordering.OrderPaging;
import com.gitee.qdbp.able.jdbc.paging.PageList;
import com.gitee.qdbp.able.result.ResultCode;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCoreBean;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCoreWhere;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCustomizeBean;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCustomizeWhere;
import com.gitee.qdbp.general.common.biz.settings.basic.SystemConfigCoreBasic;
import com.gitee.qdbp.general.common.biz.settings.basic.SystemConfigCustomizeBasic;
import com.gitee.qdbp.general.common.enums.ConfigDataType;
import com.gitee.qdbp.general.common.enums.ConfigScene;
import com.gitee.qdbp.general.common.enums.UsingState;
import com.gitee.qdbp.tools.utils.VerifyTools;

public class SystemConfigBaseQueryer {

    /** 日志对象 **/
    private static final Logger log = LoggerFactory.getLogger(SystemDataDictQueryer.class);

    protected ConfigDataType dataType;
    @Autowired
    protected SystemConfigCoreBasic systemConfigCoreBasic;
    @Autowired
    protected SystemConfigCustomizeBasic systemConfigCustomizeBasic;

    protected SystemConfigBaseQueryer(ConfigDataType dataType) {
        this.dataType = dataType;
    }

    public SystemConfigCoreBean findByKey(ConfigScene scene, String tenantCode, String key) throws ServiceException {
        if (VerifyTools.isBlank(scene)) {
            log.error("params is null: scene");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(tenantCode)) {
            log.error("params is null: tenantCode");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(key)) {
            log.error("params is null: key");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        SystemConfigCoreWhere where = new SystemConfigCoreWhere();
        where.setConfigKey(key);
        where.setDataType(dataType);
        where.setUsingState(UsingState.ENABLED);
        return find(scene, tenantCode, where);
    }

    public String findConfigValueByKey(ConfigScene scene, String tenantCode, String key) throws ServiceException {
        SystemConfigCoreBean bean = findByKey(scene, tenantCode, key);
        return bean == null ? null : bean.getConfigValue();
    }

    public Map<String, SystemConfigCoreBean> listByKeys(ConfigScene scene, String tenantCode, List<String> keys) {
        if (VerifyTools.isBlank(scene)) {
            log.error("params is null: scene");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(tenantCode)) {
            log.error("params is null: tenantCode");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(keys)) {
            log.error("params is null: keys");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        SystemConfigCoreWhere where = new SystemConfigCoreWhere();
        where.setConfigKeys(keys);
        where.setDataType(dataType);
        where.setUsingState(UsingState.ENABLED);
        PageList<SystemConfigCoreBean> list = list(scene, tenantCode, where, OrderPaging.NONE);
        Map<String, SystemConfigCoreBean> map = new HashMap<>();
        if (!list.isEmpty()) {
            for (SystemConfigCoreBean bean : list) {
                map.put(bean.getConfigKey(), bean);
            }
        }
        return map;
    }

    /** 根据条件查找 **/
    public SystemConfigCoreBean find(ConfigScene scene, String tenantCode, SystemConfigCoreWhere where)
            throws ServiceException {
        if (VerifyTools.isBlank(scene)) {
            log.error("params is null: scene");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(tenantCode)) {
            log.error("params is null: tenantCode");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 查询默认配置
        where.setSceneType(scene.name());
        where.setDataType(dataType);
        SystemConfigCoreBean bean = systemConfigCoreBasic.find(where);

        if (bean != null) {
            // 查询当前组织定制的配置
            SystemConfigCustomizeWhere w = new SystemConfigCustomizeWhere();
            w.setTenantCode(tenantCode);
            w.setConfigKey(bean.getConfigKey());
            w.setDataType(dataType);
            SystemConfigCustomizeBean customize = systemConfigCustomizeBasic.find(w);
            if (customize != null) {
                bean.setConfigValue(customize.getConfigValue());
                bean.setConfigText(customize.getConfigText());
            }
        }

        return bean;
    }

    public PageList<SystemConfigCoreBean> list(ConfigScene scene, String tenantCode, SystemConfigCoreWhere where,
            OrderPaging paging) {
        if (VerifyTools.isBlank(scene)) {
            log.error("params is null: scene");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(tenantCode)) {
            log.error("params is null: tenantCode");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 查询默认配置
        where.setSceneType(scene.name());
        where.setDataType(dataType);
        PageList<SystemConfigCoreBean> list = systemConfigCoreBasic.list(where, paging);

        if (VerifyTools.isNotBlank(list)) {
            // 收集ConfigKey
            Set<String> customizeConfigKeys = new HashSet<>();
            for (SystemConfigCoreBean bean : list) {
                if (Boolean.TRUE.equals(bean.getEditable())) { // 只有可编辑的记录才需要查询组织定制的配置值
                    customizeConfigKeys.add(bean.getConfigKey());
                }
            }
            // 查询当前组织定制的配置值
            PageList<SystemConfigCustomizeBean> customizes = null;
            if (!customizeConfigKeys.isEmpty()) {
                SystemConfigCustomizeWhere w = new SystemConfigCustomizeWhere();
                w.setTenantCode(tenantCode);
                w.setConfigKeys(new ArrayList<>(customizeConfigKeys));
                w.setDataType(dataType);
                customizes = systemConfigCustomizeBasic.list(w, OrderPaging.NONE);
            }
            if (VerifyTools.isNotBlank(customizes)) {
                // 生成KEY映射结构
                Map<String, SystemConfigCustomizeBean> map = new HashMap<>();
                for (SystemConfigCustomizeBean bean : customizes) {
                    map.put(bean.getConfigKey(), bean);
                }
                // 用当前组织定制的值替换默认的配置值
                for (int i = 0; i < list.size(); i++) {
                    SystemConfigCoreBean bean = list.get(i);
                    SystemConfigCustomizeBean customize = map.get(bean.getConfigKey());
                    Map<String, Object> original = new HashMap<>();
                    original.put("configValue", bean.getConfigValue());
                    original.put("configText", bean.getConfigText());
                    bean.getOptions(true).put("original", original);
                    if (customize != null) {
                        bean.getOptions(true).put("customize", true);
                        bean.setConfigValue(customize.getConfigValue());
                        bean.setConfigText(customize.getConfigText());
                    }
                }
            }
        }
        return list;
    }

}
